package cn.mw.cmdb.service.impl;

import cn.mw.cmdb.entity.DataSourceGroupInfo;
import cn.mw.cmdb.entity.DataSourceInfo;
import cn.mw.cmdb.mongoMapper.DataSourceGroupInfoMapper;
import cn.mw.cmdb.mongoMapper.DatasourceInfoMapper;
import cn.mw.cmdb.service.DataSourceGroupInfoService;
import cn.mw.cmdb.util.CMDBTool;
import cn.mw.cmdb.view.ViewConvertContext;
import cn.mw.cmdb.view.ViewManager;
import cn.mw.components.mongodb.tool.CriteriaWrapper;
import cn.mw.microMonitorCommon.api.cmdb.TreeView;
import cn.mw.microMonitorCommon.util.IDModelType;
import cn.mw.microMonitorCommon.util.ModuleIDManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class DataSourceGroupInfoServiceImpl extends BaseSearchService<DataSourceGroupInfo> implements DataSourceGroupInfoService {

    @Autowired
    private ModuleIDManager moduleIDManager;

    @Autowired
    private DataSourceGroupInfoMapper dataSourceGroupInfoMapper;

    @Autowired
    private DatasourceInfoMapper datasourceInfoMapper;

    @Autowired
    private ViewManager viewManager;

    private static final String OTHER_GROUP_DESC="其它";

    @Override
    public boolean addOrUpdateDataSourceGroupInfo(DataSourceGroupInfo dataSourceGroupInfo) {
        if (StringUtils.isBlank(dataSourceGroupInfo.getId())) {
            // 执行新增
            dataSourceGroupInfo.setId(moduleIDManager.getIDStr(IDModelType.Model));
            dataSourceGroupInfoMapper.insert(dataSourceGroupInfo);
        } else {
            Query query;
            try {
                query = new Query(CriteriaWrapper.where(DataSourceGroupInfo::getId).is(dataSourceGroupInfo.getId()));
                Update update = CMDBTool.genMongoUpdate(dataSourceGroupInfo, null, null);
                CMDBTool.updateFirst(dataSourceGroupInfoMapper, query, update);
            } catch (Exception e) {
                throw new RuntimeException("update datasource error!", e);
            }
        }
        return true;
    }

    @Override
    public boolean deleteDataSourceGroupInfo(String groupId) throws Exception {
        Query query = new Query(new Criteria().orOperator(CriteriaWrapper.where(DataSourceGroupInfo::getId).is(groupId)
                , CriteriaWrapper.where(DataSourceGroupInfo::getGroupPath).in(groupId)));
        dataSourceGroupInfoMapper.remove(query);

        Query dataSourceQuery = new Query(CriteriaWrapper.where(DataSourceInfo::getGroupPath).in(groupId));
        datasourceInfoMapper.remove(dataSourceQuery);
        return true;
    }

    @Override
    public DataSourceGroupInfo getGroupInfo(String groupId) throws Exception {
        Query query = new Query(CriteriaWrapper.where(DataSourceGroupInfo::getId).is(groupId));
        return dataSourceGroupInfoMapper.findOne(query);
    }

    @Override
    public Object getGroupTree() throws Exception {
        List<TreeView> groupInfoList = dataSourceGroupInfoMapper.find(new Query());
        // 添加未分组的数据源
        List<DataSourceInfo> dataSourceInfoList = datasourceInfoMapper.find(new Query());
        Map<String, Integer> groupId2DataSourceCountMap = new HashMap<>();
        String groupKey;
        for (DataSourceInfo dataSourceInfo : dataSourceInfoList) {
            if (CollectionUtils.isNotEmpty(dataSourceInfo.getGroupPath())) {
                dataSourceInfo.getGroupPath().forEach(item -> {
                    String groupId = item == null ? "" : item;
                    if (!groupId2DataSourceCountMap.containsKey(groupId)) {
                        groupId2DataSourceCountMap.put(groupId, 0);
                    }
                    groupId2DataSourceCountMap.put(groupId, groupId2DataSourceCountMap.get(groupId) + 1);
                });
            }
        }
        if (groupId2DataSourceCountMap.containsKey("")) {
            DataSourceGroupInfo otherGroup = new DataSourceGroupInfo();
            otherGroup.setName(OTHER_GROUP_DESC);
            otherGroup.setId("");
            groupInfoList.add(otherGroup);
        }
        groupInfoList.forEach(item -> {
            item.setCount(groupId2DataSourceCountMap.getOrDefault((String) item.getId(), 0));
        });
        ViewConvertContext context = new ViewConvertContext();
        return viewManager.getTreeViewObject(groupInfoList, context);
    }

    @Override
    protected DataSourceGroupInfo genObject() {
        return new DataSourceGroupInfo();
    }
}
